package com.kimstore.dao.impl;

import com.kimstore.bean.Customer;
import java.util.List;

import javax.persistence.Query;

import com.kimstore.dao.ItemDao;
import com.kimstore.bean.Item;
import com.kimstore.bean.ItemStatus;
import com.kimstore.bean.Product;
import com.kimstore.bean.RepairDetail;
import java.util.Date;

public class ItemDaoImpl extends GenericJpaDaoImpl<Item, Integer> implements ItemDao {

    @Override
    public void saveOrUpdate(Item i) {
        String status = null;
        if (i.getPurchaseDetail() == null) {
            if (i.getRepairDetail() == null) {
                status = ItemStatus.AVAILABLE;
            } else {
                status = ItemStatus.OFFICE_PROPERTY;
            }
        } else {
            if (i.getRepairDetail() == null) {
                status = ItemStatus.SOLD;
            } else {
                if (i.getRepairDetail().getCurrentStatus().equals(RepairDetail.IN_REPAIR)) {
                    status = ItemStatus.IN_REPAIR;
                } else {
                    if (i.getRepairDetail().getVerdict().equals(RepairDetail.RELEASE)) {
                        status = ItemStatus.SOLD;
                    } else {
                        status = ItemStatus.OFFICE_PROPERTY;
                    }
                }
            }
        }
        i.setLatestStatus(status);

        beginTransaction();
        getEntityManager().merge(i);
        commit();

        closeEntityManager();

    }

    @Override
    @SuppressWarnings("unchecked")
    public List<Item> getAllAvailableItems() {
        Query query = getEntityManager().createQuery("SELECT item FROM Item item where item.purchaseDetail is null and item.repairDetail is null");
        List<Item> items = query.getResultList();

        return items;
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<Item> getAvailableItemsByProduct(Product product) {
        Query query = getEntityManager().createQuery("SELECT item FROM Item item, Order o WHERE item NOT IN elements(o.items) and item NOT IN elements(o.freebies) and item.product = :product and item.repairDetail is null");
        query.setParameter("product", product);
        List<Item> items = query.getResultList();

        return items;
    }

    @Override
    public Item findBySerial(String serial) {
        Query query = getEntityManager().createQuery("Select item from Item item where item.serial = :serial");
        query.setParameter("serial", serial);
        Item items = (Item) getSingleResultOrNull(query);

        return items;
    }

    @Override
    public List<Item> getAllFreebies() {
        Query query = getEntityManager().createQuery("Select item.purchaseDetail.freebies from Item item");
        List<Item> items = query.getResultList();

        return items;
    }

    @Override
    public List<Item> getCustomerPurchases(Customer customerName) {
        Query query = getEntityManager().createQuery("Select item from Item item where item.purchaseDetail.customer = :customer order by item.purchaseDetail.dateSold DESC");
        query.setParameter("customer", customerName);

        List<Item> items = query.getResultList();

        return items;
    }

    @Override
    public boolean existsSerial(String serial) {
        Query query = getEntityManager().createQuery("select count(item) from Item item where item.serial = :serial");
        query.setParameter("serial", serial);
        long count = (long) query.getSingleResult();

        return count > 0;
    }

    @Override
    public List<Item> getAllSoldItems() {
        Query query = getEntityManager().createQuery("SELECT item FROM Item item where item.purchaseDetail is not null  and item.repairDetail is null order by item.purchaseDetail.customer, item.product, item.serial");
        List<Item> items = query.getResultList();

        return items;
    }
    
    @Override
    public List<Item> getAllSoldItems(Date startDate, Date endDate) {
        Query query = getEntityManager().createQuery("SELECT item FROM Item item where item.purchaseDetail is not null  and item.repairDetail is null and item.purchaseDetail.dateSold between :startDate and :endDate order by item.purchaseDetail.customer, item.product, item.serial");
        query.setParameter("startDate", startDate);
        query.setParameter("endDate", endDate);
        
        List<Item> items = query.getResultList();

        return items;
    }

    @Override
    public List<Item> findAll(int startIndex, int maxNumber) {
        Query query = getEntityManager().createQuery("from Item item by item.serial");
        query.setFirstResult(startIndex);
        query.setMaxResults(maxNumber);

        List<Item> items = query.getResultList();

        return items;
    }

    @Override
    public long count() {
        Query query = getEntityManager().createQuery("Select count(item) from Item item");
        long count = (long) query.getSingleResult();


        return count;
    }

    @Override
    public List<Item> getAllItemsWithRepair(Date startDate, Date endDate) {
        Query query = getEntityManager().createQuery("SELECT item FROM Item item where item.repairDetail is not null and item.repairDetail.receiveDate between :startDate and :endDate");
        query.setParameter("startDate", startDate);
        query.setParameter("endDate", endDate);
        
        List<Item> items = query.getResultList();

        return items;    }
}
